package com.sherlocky.util;

import java.io.StringReader;
import java.io.StringWriter;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.collections.MapUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import freemarker.ext.beans.BeansWrapper;
import freemarker.template.Configuration;
import freemarker.template.ObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateHashModel;
import freemarker.template.TemplateModelException;

public class TemplateUtil {
	private static Log logger = LogFactory.getLog(TemplateUtil.class);
	
	private static Pattern tplP = Pattern.compile("\\{([^\\}]*)\\}");
	/**
	 * freemarker模板解析
	 * @param templateStr
	 * @param vObject
	 * @return
	 */
	public static String freemarker(String templateStr, Object vObject) {
		if(vObject == null) {
			return templateStr;
		}
		Template t;
		StringWriter stringWriter = new StringWriter();
		Configuration cfg = new Configuration();
		cfg.setObjectWrapper(ObjectWrapper.BEANS_WRAPPER);
		cfg.setEncoding(Locale.getDefault(), "UTF-8");
		
		try {
			//freemarker在解析数据格式的时候，自动默认将数字按3为分割（1，000），需要禁用掉
			String disableNumberParserStr = "<#setting number_format=\"#\">";
			t = new Template("dao template parser",
					new StringReader(disableNumberParserStr + templateStr), cfg);

			t.process(vObject, stringWriter);
			stringWriter.toString();
		} catch (Exception e) {
			logger.error("解析模板" + templateStr + "出错,数据:" + vObject, e);
			return templateStr;
		}
		return stringWriter.toString();
	}

	/**
	 * freemarker模板解析
	 * @param templateStr
	 * @param vObject
	 * @param staticClasses 静态类配置，可以在模板中使用调用java静态方法
	 * @return
	 */
	public static String freemarker(String templateStr, Map<String, Object> vObject, Map<String, String> staticClasses) {
		if(vObject == null) {
			return templateStr;
		}
		Template t;
		StringWriter stringWriter = new StringWriter();
		Configuration cfg = new Configuration();
		cfg.setObjectWrapper(ObjectWrapper.BEANS_WRAPPER);
		cfg.setEncoding(Locale.getDefault(), "UTF-8");
		if(staticClasses != null) {
			TemplateHashModel staticModels = ((BeansWrapper)cfg.getObjectWrapper()).getStaticModels();
			for (Entry<String, String> entry : staticClasses.entrySet()) {
				try {
					vObject.put(entry.getKey(), staticModels.get(entry.getValue()));
				} catch (TemplateModelException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		
		try {
			//freemarker在解析数据格式的时候，自动默认将数字按3为分割（1，000），需要禁用掉
			String disableNumberParserStr = "<#setting number_format=\"#\">";
			t = new Template("dao template parser",
					new StringReader(disableNumberParserStr + templateStr), cfg);

			t.process(vObject, stringWriter);
			stringWriter.toString();
		} catch (Exception e) {
			logger.error("解析模板" + templateStr + "出错,数据:" + vObject, e);
			return templateStr;
		}
		return stringWriter.toString();
	}
	
	/**
	 * 替换{XXX}这个格式的值，与util中tpl方法一致
	 * @param templateStr
	 * @param vObject
	 * @return
	 */
	public static String tpl(String templateStr, Map map){
		Matcher m = tplP.matcher(templateStr);
		if(map == null || !m.find()) return templateStr;
		StringBuffer sb = new StringBuffer();
		do{
			String key = m.group(1);
			String value = MapUtils.getString(map, key); 
			if(value != null){
				m.appendReplacement(sb, value);
			}
		}while(m.find());
		m.appendTail(sb);
		return sb.toString();
	}
}
